#include <SimpleDef.h>
#include <Utility/CLib.h>
#include <Kernel/syscall.h>
/*
@brief 格式化打印
@param lpcsFmt 格式化字符串
@nColor 字符颜色
@... 可变参数
@return 打印的字符数
@note 目前支持 %d %u %x %c %s
@note 由于需要接收可变参数个数，因此采用 C 调用约定
*/
int printf(LPCSTR lpszFmt, ...)
{
    int ret = 0;
    int i = 0 ; /* 缓冲区索引 */
    char line[128]; /* 行缓冲区 */
    LPINT lpParamBase = (LPINT)&lpszFmt + 1; /* 首个参数地址 */
    DWORD dwIndex = 0u; /* 第几个参数 */
    BOOL bParseFlag = FALSE;
    while (*lpszFmt)
    {
        if (i > 80) /* 超过一行 */
        {
            ret += WriteConsole(line) - 1;
            i = 0;
            line[0] = '\0';
        }
        if (!bParseFlag) /* 当前字符不解析 */
        {
            if (*lpszFmt == '%') /* 下个字符解析 */
            {
                bParseFlag = TRUE; /* 下个字符解析 */
            }
            else if (*lpszFmt == '\n') /* 换行 */
            {
                line[i++] = '\n';
                line[i] = '\0'; /* 一行结束 */
                i = 0;
                ret += WriteConsole(line) - 1; /* 行缓冲模式 */
            }
            else
            {
                line[i++] = *lpszFmt;
            }
            lpszFmt++; /* 下个字符 */
        }
        else /* 当前字符解析 */
        {            
            bParseFlag = FALSE; /* 下个字符不解析  */
            if (*lpszFmt == 'd') /* 整数 */
            {
                itoa(*(int*)(lpParamBase + dwIndex), line + i, 10);
                i += strlen(line + i);
                dwIndex++;
            }
            else if (*lpszFmt == 'u') /* 无符号整数 */
            {
                utoa(*(unsigned int*)(lpParamBase + dwIndex), line + i, 10);
                i += strlen(line + i);
                dwIndex++;
            }
            else if (*lpszFmt == 'x') /* 十六进制 */
            {
                itoa(*(int*)(lpParamBase + dwIndex), line + i, 16);
                i += strlen(line + i);
                dwIndex++;
            }
            else if (*lpszFmt == 'c') /* 字符，传参时字符提升为 4 字节 */
            {
                line[i++] = (char)*(int*)(lpParamBase + dwIndex);
                dwIndex++;
            }
            else if (*lpszFmt == 's') /* 字符串 */
            {
                line[i] = '\0'; /* 遇到字符串直接清空行缓冲区 */
                ret += WriteConsole(line) - 1;
                i = 0;
                line[0] = '\0';
                LPCSTR lpcs = (LPCSTR)*(lpParamBase + dwIndex); /* 指向字符串的指针 */
                ret += WriteConsole(lpcs) - 1; /* 打印字符串 */
                dwIndex++;
            }
            else if (*lpszFmt == '%') /* 转义 */
            {        
                line[i++] = '%';
            }
            lpszFmt++;
        }
    }
    if (i > 0)
    {
        line[i] = '\0';
        ret += WriteConsole(line) - 1;
    }
    return ret;
}